import hashlib
import wmi
import zlib
import base64
import rsa
from rsa import common


def md5(str) -> str:
    '''md5计算返回小写16进制字符串'''
    md5_obj=hashlib.md5(str.encode("utf-8"))
    md5str = md5_obj.hexdigest()
    return md5str

def md5Upper(str) -> str:
    '''md5计算返回大写16进制字符串'''
    return md5(str).upper()


def encode_b62(n):
    '''62位编码'''
    table = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    result = []
    temp = n
    if 0 == temp:
        result.append('0')
    else:
        while 0 < temp:
            result.append(table[temp % 62])
            temp = int(temp/62)
    return ''.join([x for x in reversed(result)])

def base64encode(s:str):
    encoder = base64.b64encode(s.encode("utf-8"))
    str_encoder = encoder.decode('utf-8')
    return str_encoder 

def base64decode(str_encoder:str):
    decoder = base64.b64decode(str_encoder)
    s = decoder.decode('utf-8')
    return s 


class RSACipher:
    PUBLIC_KEY_PATH = 'rsa_public_key.pem'  # 公钥
    PRIVATE_KEY_PATH = 'rsa_private_key.pem'  # 私钥

    # 初始化key
    def __init__(self,
                 public_key_file=None,
                 private_key_file=None):

        if public_key_file:
            self.pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(open(public_key_file).read())
        if private_key_file:
            self.privkey = rsa.PrivateKey.load_pkcs1(open(private_key_file).read())

    @staticmethod
    def params_sort(params: dict) -> str:
        """
        参数 按照ASCII排序
        :param params: 参数dict
        :return: dict
        """
        params = sorted(params.items(), key=lambda item: item[0], reverse=False)
        return '&'.join([key + '=' + str(val) for key, val in params if key != 'sign'])

    def sign(self, params_str: str) -> str:
        """
        获取签名
        :param params: 加签数据
        :return: str
        """
#        params_str = RSACipher.params_sort(params)
        sign = rsa.sign(params_str.encode(), self.privkey, 'SHA-1')
        return base64.b64encode(sign).decode()

    def verify_sign(self, params_str: str,sign: str) -> bool:
        """
        签名验证
        :param pubkey: pubkey验证
        :param params: 验证数据
        :return: bool
        """
        try:
#            sign = params.get('sign')
#            params_str = RSACipher.params_sort(params)
            rsa.verify(params_str.encode(), base64.b64decode(sign), self.pubkey)
            return True
        except Exception as e:
            print(e)
            return False

    def encrypt(self, params: str) -> str:
        """
        数据公钥加密
        :param pubkey: pubkey加密
        :param params: 加密数据
        :return: data
        """
        encrypt_str = rsa.encrypt(params.encode(), self.pubkey)
        return base64.b64encode(encrypt_str).decode()

    def decrypt(self, sign: str):
        """
        数据私钥解密
        :param sign: 带解密字符串
        :return:
        """
        try:
            res = rsa.decrypt(base64.b64decode(sign), self.privkey)
            if isinstance(res, bytes):
                res = res.decode()
            return res
        except Exception as e:
            print(e)
            return None
